var newTime = 1, oldTime = 0, FPS = 0, vFPS, servFPS = 0, mFPS = 0, tickTime = 200;
var newTimeDraw = 0, oldTimeDraw = 0;
var newTimeServer = 0, oldTimeServer = 0;
var CANVAS_WIDTH = 867;	// Canvas width
var CANVAS_HEIGHT = 620;	// Canvas height
var SCALE = 1;
//var canvasCenterX = 0;
//var canvasCenterY = 0;
var angleAidkit = 0;
var dx = 0, dy = 0;//смещение карты или позиция камеры.
var PAUSE = false;
var GAME = false;
var objects = [];
objects.heroes = [];
objects.arrows = [];
objects.towers = [];
objects.explosionBloods = [];
objects.unitsStaticInfo = [];
var basicHeroList = [];
var animationCanvasList = [];
var selectedObject = {id: -1, type: -1, x: -1, y: -1};
function initMapCanvas(fnSuccess) {
    var imgMap = new Image();
    imgMap.onload = function () {
        $("#mapCanvas").attr("height", Math.round(imgMap.height * SCALE) + 1);
        $("#mapCanvas").attr("width", Math.round(imgMap.width * SCALE) + 1);
        mapCanvas.scale(SCALE, SCALE);
        mapCanvas.drawImage(
                imgMap
                , 0
                , 0);
        fnSuccess();
    }
    imgMap.src = "maps/img/map_new.jpg";
}
function initHpCanvas() {
    $("#hpCanvas").attr("height", 5 * 60);
    $("#hpCanvas").attr("width", 6 * 60);
    hpCanvas.fillStyle = "rgba(0,0,0,0.6)";
    hpCanvas.fillRect(0, 0, 6 * 60, 5 * 60);
    var imgHp = new Image();
    imgHp.onload = function () {
        for (var i = 1; i < 60; i++) {
            hpCanvas.drawImage(
                    imgHp
                    , 0
                    , 0
                    , i
                    , 5
                    , 0
                    , i * 5
                    , i
                    , 5);
        }
    };
    imgHp.src = "img/resource/hp.png";

    var imgHpAllies = new Image();
    imgHpAllies.onload = function () {
        for (var i = 1; i < 60; i++) {
            hpCanvas.drawImage(
                    imgHpAllies
                    , 0
                    , 0
                    , i
                    , 5
                    , 60
                    , i * 5
                    , i
                    , 5);
        }
    }
    imgHpAllies.src = "img/resource/hp_allies.png";

    var imgHpAnemy = new Image();
    imgHpAnemy.onload = function () {
        for (var i = 1; i < 60; i++) {
            hpCanvas.drawImage(
                    imgHpAnemy
                    , 0
                    , 0
                    , i
                    , 5
                    , 120
                    , i * 5
                    , i
                    , 5);
        }
    }
    imgHpAnemy.src = "img/resource/hp_anemy.png";

    var imgHpAlliesHero = new Image();
    imgHpAlliesHero.onload = function () {
        for (var i = 1; i < 60; i++) {
            hpCanvas.drawImage(
                    imgHpAlliesHero
                    , 0
                    , 0
                    , i
                    , 5
                    , 180
                    , i * 5
                    , i
                    , 5);
        }
    }
    imgHpAlliesHero.src = "img/resource/hp_allies_hero.png";

    var imgHpAnemyHero = new Image();
    imgHpAnemyHero.onload = function () {
        for (var i = 1; i < 60; i++) {
            hpCanvas.drawImage(
                    imgHpAnemyHero
                    , 0
                    , 0
                    , i
                    , 5
                    , 240
                    , i * 5
                    , i
                    , 5);
        }
    }
    imgHpAnemyHero.src = "img/resource/hp_anemy_hero.png";

    var imgMp = new Image();
    imgMp.onload = function () {
        for (var i = 1; i < 60; i++) {
            hpCanvas.drawImage(
                    imgMp
                    , 0
                    , 0
                    , i
                    , 5
                    , 300
                    , i * 5
                    , i
                    , 5);
        }
    }
    imgMp.src = "img/resource/mp.png";
}
function initHeroesList() {
    $.ajax({
        type: "GET",
        url: "ajax_request_api/getHeroesList",
        dataType: "json",
        cache: false,
        data: {
            type: "getHeroesList"
        },
        success: function (data) {
            if (data.status === "success") {
                basicHeroList = data.heroesList;
                initHeroMenuList();
            } else {
                alert(data.msg);
            }
        }
    });
}
function getBasicHero(id) {
    for (var i = 0; i < basicHeroList.length; i++) {
        if (id == basicHeroList[i].id) {
            return basicHeroList[i];
        }
    }
}
function cFPS() {
    newTime = new Date().getTime();
    FPS = FPS + 1;
    if (newTime - oldTime > 1000)
    {
        vFPS = FPS;
        servFPS = mFPS;
        mFPS = 0;
        FPS = 0;
        // document.ws.logMessage("КБит/с Вх-" + Math.round((myByteIn / 64) * 10) / 10 + " Исх-" + Math.round((myByteOut / 64) * 10) / 10);
        myByteIn = 0;
        myByteOut = 0;
        oldTime = newTime;
        $("#ultFPS").html('FPS: ' + vFPS + " / " + servFPS);
    }
}
function resizeWindow() {
    if (isFullScreen()) {
        CANVAS_HEIGHT = $(window).height();
    } else {
        CANVAS_HEIGHT = $(window).height() - 1;
    }
    if (CANVAS_HEIGHT >= 1024) {
        SCALE = 1;
        speedMoveCanvas = 30;
    } else {
        SCALE = parseFloat((CANVAS_HEIGHT / 1024).toFixed(1));
        speedMoveCanvas = 30 * SCALE;
    }
    CANVAS_WIDTH = $(window).width();
    $("#gameCanvas").attr("width", Math.floor(CANVAS_WIDTH));
    $("#gameCanvas").attr("height", Math.floor(CANVAS_HEIGHT));
    PAUSE = true;
    $("#initWindow").show();
    $("#initWindow").html("Масштабирование графики " + SCALE + "</br>0%");
    initMapCanvas(function () {
        $("#initWindow").html("Масштабирование графики " + SCALE + "</br>5%");
        initCanvasHeroes(basicHeroList, 0, function () {
            console.log("initCanvasHeroes");
            $("#initWindow").hide();
            PAUSE = false;
        });
    });
    initCanvasBaseStyle();
}
function calcMouse() {
    if (isFullScreen() || isMoveRight || isMoveLeft || isMoveDown || isMoveUp) {
        if (curX > $(window).width() - 20 || isMoveRight) {
            moveRight();
        } else if (curX < 20 || isMoveLeft) {
            moveLeft();
        }
        if (curY > $(window).height() - 10 || isMoveDown) {
            moveDown();
        } else if (curY < 20 || isMoveUp) {
            moveUp();
        }
    }
}
function exitRoom() {
    ws.sendMessage("qu");
    GAME = false;
    initPage("menu");
}
window.requestAnimFrame = (function () {
    return  window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function (/* function */callback, /* DOMElement */element) {
                window.setTimeout(callback, 17);
            };
})();
window.cancelRequestAnimFrame = (function () {
    return window.cancelAnimationFrame ||
            window.webkitCancelRequestAnimationFrame ||
            window.mozCancelRequestAnimationFrame ||
            window.oCancelRequestAnimationFrame ||
            window.msCancelRequestAnimationFrame ||
            clearTimeout;
})();
var requestLinkAnimFrame;
function animate() {
    if (GAME) {
        requestLinkAnimFrame = requestAnimFrame(function () {
            animate();
        });
        if (!PAUSE) {
            draw();
        }
    } else {
        cancelRequestAnimFrame(requestLinkAnimFrame);
    }
}


function calc(objects) {
    var obj = objects.heroes;
    var delay = newTimeDraw - oldTimeDraw;
    for (var j = 0; j < obj.length; j++) {
        var nx = obj[j].x + delay * obj[j].dx;
        var ny = obj[j].y + delay * obj[j].dy;
        var distance = distans(obj[j].x, obj[j].y, nx, ny);
        if (distance > 0.1) {
            obj[j].x = nx;
            obj[j].y = ny;
        }
        obj[j].r = obj[j].r + delay * obj[j].dr;
        var maxFrameA = 1;
        var speedFrame = 1;
        if (obj[j].type_animation == "run" && obj[j].next_animation != "run") {
            if (obj[j].fw < 25) {
                obj[j].fw -= 2;
                if (obj[j].fw <= 0) {
                    obj[j].fw = 0;
                }
            }
        }
        if (obj[j].type_animation == "atack1" || obj[j].type_animation == "atack2" || obj[j].type_animation == "atack3") {
            if (obj[j].fw == 0) {
                obj[j].type_animation = obj[j].next_animation;
            }
        } else if (obj[j].type_animation == "run") {
            if (obj[j].fw == 0) {
                obj[j].type_animation = obj[j].next_animation;
            }
        } else {
            obj[j].type_animation = obj[j].next_animation;
        }
        // if (obj[j].fw == 0 || obj[j].animation != 2) {
        //     obj[j].type_animation = obj[j].next_animation;
        // }
        if (obj[j].type_animation == 'run') {
            var width = getPicture('heroes/' + obj[j].dir, 'run', 'png').width;
            maxFrameA = Math.round(width / obj[j].imgW) - 1;
            // $("#log").html('heroes/' + obj[j].dir + " " + width + " " + maxFrameA);
            speedFrame = 15;
        } else if (obj[j].type_animation == 'stand') {
            maxFrameA = 40;
            speedFrame = 15;
        } else if (obj[j].type_animation == 'atack1') {
            maxFrameA = 60;
            speedFrame = 15;
        } else if (obj[j].type_animation == 'atack2') {
            maxFrameA = 60;
            speedFrame = 15;
        } else if (obj[j].type_animation == 'atack3') {
            maxFrameA = 60;
            speedFrame = 15;
        }
        if ((newTimeDraw - obj[j].time_last_change_frame) > speedFrame) {
            if (obj[j].fw < maxFrameA) {
                if (obj[j].type_animation == 'stand') {
                    obj[j].fw += delay * 0.03;
                } else if (obj[j].type_animation == 'atack1' || obj[j].type_animation == 'atack2' || obj[j].type_animation == 'atack3') {
                    obj[j].fw += delay * (0.06 + 0.06 * (5 - Math.round(obj[j].ticksBetweanAttack / 2)) / 5);
                } else {
                    obj[j].fw += delay * 0.06;
                }
                obj[j].fw = Math.round(obj[j].fw) < maxFrameA ? obj[j].fw : 0;
            } else {
                obj[j].fw = 0;
            }
            obj[j].time_last_change_frame = newTimeDraw;
        }
        //if (obj[j].id == meId)
        //$("#log").html(obj[j].type_animation);
    }
    for (var j = 0; j < objects.arrows.length; j++) {
        var nx = objects.arrows[j].x + delay * objects.arrows[j].dx;
        var ny = objects.arrows[j].y + delay * objects.arrows[j].dy;
        var distance = distans(objects.arrows[j].x, objects.arrows[j].y, nx, ny);
        if (distance > 0.1) {
            objects.arrows[j].x = nx;
            objects.arrows[j].y = ny;
        }
        objects.arrows[j].r = objects.arrows[j].r + delay * objects.arrows[j].dr;
        objects.arrows[j].f += delay * 0.06;
        if (Math.round(objects.arrows[j].f) < 30) {
            objects.arrows[j].f = Math.round(objects.arrows[j].f);
        } else {
            objects.arrows[j].f = 0;
        }
    }
    for (var j = 0; j < objects.explosionBloods.length; j++) {
        objects.explosionBloods[j].f += delay * 0.06;
        var maxF = 16;
        if (objects.explosionBloods[j].type == 2) {
            var width = getPicture('heroes/' + objects.explosionBloods[j].dir, 'explosion', 'png').width;
            maxF = Math.round(width / 128) - 1;
            //maxF = 15;
            // }else if (objects.explosionBloods[j].dir == "clinkz") {
            // maxF = 39;
        } else if (objects.explosionBloods[j].type == 3) {
            maxF = 120;
        }
        //$("#log").html(width);
        if (Math.round(objects.explosionBloods[j].f) < maxF) {
            objects.explosionBloods[j].f = Math.round(objects.explosionBloods[j].f);
        } else {
            objects.explosionBloods.splice(j, 1);
            j--;
        }
    }
    oldTimeDraw = newTimeDraw;
}
function goToHero(id) {
    var tmpHero = getBObject(id);
    dx = tmpHero.x - CANVAS_WIDTH / SCALE / 2;
    dy = tmpHero.y - CANVAS_HEIGHT / SCALE / 2;
    moveRight();
    moveDown();
    moveLeft();
    moveUp();
    ws.sendMessage("medl" + String.fromCharCode(Math.round(tmpHero.x)) + String.fromCharCode(Math.round(tmpHero.y)));
}
function getMe() {
    for (var j = 0; j < objects.heroes.length; j++) {
        if (objects.heroes[j].id == meId) {
            return objects.heroes[j];
        }
    }
}
function setNameObj(obj) {
    var tmp_i = -1;
    for (var t = 0; t < objects.unitsStaticInfo.length; t++) {
        if (obj.id === objects.unitsStaticInfo[t].gameId) {
            tmp_i = t;
            break;
        }
    }
    if (tmp_i !== -1) {
        var tmpBasicHero = getBasicHero(objects.unitsStaticInfo[tmp_i].heroId);
        obj.name = tmpBasicHero.name;
        obj.dir = tmpBasicHero.dir;
        //obj.name += obj.lvl + " " + objects.unitsStaticInfo[tmp_i].id + " " + obj.hp + "/" + obj.maxHp;
        obj.heroId = objects.unitsStaticInfo[tmp_i].heroId;
        obj.teamId = objects.unitsStaticInfo[tmp_i].teamId;
        obj.typeId = objects.unitsStaticInfo[tmp_i].typeId;
        if (obj.typeId == 4) {
            obj.imgW = 120;
        } else {
            obj.imgW = heroSize;
        }
    } else {
        obj.name = "None Info";
        obj.heroId = "1";
        obj.dir = "juggernaut";
    }
}
function setArrowNextStep(objU, obj) {
    objU.isExist = true;
    objU.x = objU.xn;
    objU.y = objU.yn;
    objU.xn = obj.xn;
    objU.yn = obj.yn;
    objU.dx = (objU.xn - objU.x) / tickTime;
    objU.dy = (objU.yn - objU.y) / tickTime;
    //угол
    objU.r = objU.rn;
    objU.rn = obj.rn;
    var angle = fixAngle(objU.rn - objU.r);
    objU.dr = (angle < 180 ? angle : angle - 360) / tickTime;
    objU.isDraw = true;
}
function setTowerNextStep(objU, obj) {
    objU.isExist = true;
    objU.x = objU.xn;
    objU.y = objU.yn;
    objU.xn = obj.xn;
    objU.yn = obj.yn;
    objU.dx = (objU.xn - objU.x) / tickTime;
    objU.dy = (objU.yn - objU.y) / tickTime;

    if (objU.animation != obj.animation && obj.animation != 0 && obj.animation != 1) {
        objU.fw = 0;
    }
    objU.animation = obj.animation;
    if (objU.animation == 0) {
        objU.next_animation = 'stand';
    } else if (objU.animation == 1) {
        objU.next_animation = 'run';
    } else if (objU.animation == 2) {
        if (objU.type_animation != 'atack') {
            objU.next_animation = 'atack';
        }
    }
    //угол
    objU.r = objU.rn;
    objU.rn = obj.rn;
    var angle = fixAngle(objU.rn - objU.r);
    objU.dr = (angle < 180 ? angle : angle - 360) / tickTime;
    objU.isDraw = true;
    objU.hp = obj.hp;
    objU.maxHp = obj.maxHp;
    objU.teamId = obj.teamId;
}
function setHeroesNextStep(objU, obj) {
    objU.isExist = true;
    objU.x = objU.xn;
    objU.y = objU.yn;
    objU.xn = obj.xn;
    objU.yn = obj.yn;
    objU.dx = (objU.xn - objU.x) / tickTime;
    objU.dy = (objU.yn - objU.y) / tickTime;
    if (objU.animation != obj.animation && obj.animation != 0 && obj.animation != 1) {
        objU.fw = 0;
    }
    objU.animation = obj.animation;
    /*if (Math.abs(objU.dx) >= 0.01 || Math.abs(objU.dy) >= 0.01) {
     objU.next_animation = 'run';
     } else if (objU.type_animation != "atack1") {
     objU.next_animation = 'stand';
     }*/
    if (objU.animation == 0) {
        objU.next_animation = 'stand';
    } else if (objU.animation == 1) {
        objU.next_animation = 'run';
    } else if (objU.animation == 2) {
        //если он сейчас не атакует
        if (objU.type_animation != 'atack1' && objU.type_animation != 'atack2' && objU.type_animation != 'atack3') {
            var rnd = Math.random();
            if (rnd < 0.3) {
                objU.next_animation = 'atack1';
            } else if (rnd < 0.6) {
                objU.next_animation = 'atack2';
            } else {
                objU.next_animation = 'atack3';
            }
        }
    }
    //угол
    objU.r = objU.rn;
    objU.rn = obj.rn;
    var angle = fixAngle(objU.rn - objU.r);
    objU.dr = (angle < 180 ? angle : angle - 360) / tickTime;
    if (obj.lvl > objU.lvl) {
        var blood = {
            x: objU.x,
            y: objU.y,
            hero: objU,
            r: Math.floor(Math.random() * 360),
            type: 3,
            f: 0
        }
        objects.explosionBloods.push(blood);
    }
    objU.lvl = obj.lvl;
    if (obj.hp < objU.hp) {
        var blood = {
            x: objU.x,
            y: objU.y,
            r: Math.floor(Math.random() * 360),
            type: 1,
            f: 0
        }
        objects.explosionBloods.push(blood);
    }
    objU.hp = obj.hp;
    objU.maxHp = obj.maxHp;
    objU.ticksBetweanAttack = obj.ticksBetweanAttack;
    setNameObj(objU);
}
function parseArrows(txt) {
    for (var i = 0; i < txt.length; i = i + 5) {
        var arrow = {
            id: txt.charCodeAt(i),
            isExist: true,
            x: 0,
            y: 0,
            xn: txt.charCodeAt(i + 1) / 5, //Позиция на сервере точка в которую юнит будет перемешен, т.е между тиками сервера в рисовании будет промежуточная точка между х и xn
            yn: txt.charCodeAt(i + 2) / 5,
            dx: 0, //прирашение между тиками с сервера
            dy: 0,
            r: 0,
            rn: txt.charCodeAt(i + 3),
            dr: 0,
            isDraw: false,
            fromHeroId: txt.charCodeAt(i + 4),
            dir: "clinkz"
        }
        var fromObj = getBObject(txt.charCodeAt(i + 4));
        if (fromObj != null) {
            arrow.dir = fromObj.dir;
        }
        var isPresent = false;
        for (var j = 0; j < objects.arrows.length; j++) {
            if (objects.arrows[j].id == arrow.id) {
                isPresent = true;
                setArrowNextStep(objects.arrows[j], arrow);
                break;
            }
        }
        if (!isPresent) {//если нет то инициализируем нов.
            arrow.x = arrow.xn;
            arrow.y = arrow.yn;
            arrow.r = arrow.rn;
            objects.arrows.push(arrow);
        }
    }
}
function parseTowers(txt) {
    for (var i = 0; i < txt.length; i = i + 9) {
        var tower = {
            id: txt.charCodeAt(i),
            isExist: true,
            x: 0,
            y: 0,
            xn: txt.charCodeAt(i + 1) / 5, //Позиция на сервере точка в которую юнит будет перемешен, т.е между тиками сервера в рисовании будет промежуточная точка между х и xn
            yn: txt.charCodeAt(i + 2) / 5,
            animation: txt.charCodeAt(i + 3),
            type_animation: 'run',
            next_animation: 'run',
            fw: 0,
            dx: 0, //прирашение между тиками с сервера
            dy: 0,
            r: 0,
            rn: txt.charCodeAt(i + 4),
            hp: txt.charCodeAt(i + 5),
            maxHp: txt.charCodeAt(i + 6),
            teamId: txt.charCodeAt(i + 7),
            dr: 0,
            isDraw: false,
            dir: "tower_" + txt.charCodeAt(i + 8)
        }
        var isPresent = false;
        for (var j = 0; j < objects.towers.length; j++) {
            if (objects.towers[j].id == tower.id) {
                isPresent = true;
                setTowerNextStep(objects.towers[j], tower);
                break;
            }
        }
        if (!isPresent) {//если нет то инициализируем нов.
            tower.x = tower.xn;
            tower.y = tower.yn;
            tower.r = tower.rn;
            objects.towers.push(tower);
        }
    }
}
function parseHeroes(txt) {
// $("#log").html("meId " + meId);
    for (var i = 0; i < txt.length; i = i + 9) {
        var hero = {
            id: txt.charCodeAt(i),
            isExist: true,
            x: 0,
            y: 0,
            dx: 0, //прирашение между тиками с сервера
            dy: 0,
            xn: txt.charCodeAt(i + 1) / 5, //Позиция на сервере точка в которую юнит будет перемешен, т.е между тиками сервера в рисовании будет промежуточная точка между х и xn
            yn: txt.charCodeAt(i + 2) / 5,
            animation: txt.charCodeAt(i + 3),
            type_animation: 'run',
            next_animation: 'run',
            fw: 0,
            time_last_change_frame: 0,
            r: 0,
            rn: txt.charCodeAt(i + 4), //угол куда смотрит
            dr: 0,
            canSee: 350,
            name: "",
            dir: "",
            heroId: 1,
            lvl: txt.charCodeAt(i + 5),
            hp: txt.charCodeAt(i + 6),
            maxHp: txt.charCodeAt(i + 7),
            ticksBetweanAttack: txt.charCodeAt(i + 8) / 10,
            typeId: 0,
            imgW: heroSize
        }
//$("#log").html(hero.xn+" "+hero.yn);
        var isPresent = false;
        for (var j = 0; j < objects.heroes.length; j++) {
            if (objects.heroes[j].id == hero.id) {
                isPresent = true;
                setHeroesNextStep(objects.heroes[j], hero);
                if (objects.heroes[j].id == meId) {
                    meTeamId = objects.heroes[j].teamId;
                }
                break;
            }
        }

        if (!isPresent) {//если нет то инициализируем нового юнита
            hero.x = hero.xn;
            hero.y = hero.yn;
            hero.r = hero.rn;
            hero.dr = 0;
            setNameObj(hero);
            objects.heroes.push(hero);
        }
//$("#log").html(objects.heroes.length)
    }
}
function parseSelected(txt) {
    var i = 1;
    if (txt.charCodeAt(0) == 0) { //User
        selectedObject = {
            type: txt.charCodeAt(0),
            id: txt.charCodeAt(i),
            strength: txt.charCodeAt(i + 1),
            agility: txt.charCodeAt(i + 2),
            intelligence: txt.charCodeAt(i + 3),
            damage: txt.charCodeAt(i + 4),
            armor: txt.charCodeAt(i + 5),
            hp: txt.charCodeAt(i + 6),
            maxHp: txt.charCodeAt(i + 7),
            mp: txt.charCodeAt(i + 8),
            maxMp: txt.charCodeAt(i + 9),
            exp: txt.charCodeAt(i + 10),
            lvl: txt.charCodeAt(i + 11),
        }
        resetselectedObject();
    } else if (txt.charCodeAt(0) == 1) {//Tower
        selectedObject = {
            type: txt.charCodeAt(0),
            id: txt.charCodeAt(i),
            damage: txt.charCodeAt(i + 1),
            armor: txt.charCodeAt(i + 2),
            hp: txt.charCodeAt(i + 3),
            maxHp: txt.charCodeAt(i + 4),
            mp: txt.charCodeAt(i + 5),
            maxMp: txt.charCodeAt(i + 6),
        }
        resetSelectedTower();
    }
}
function drawMapNew(ctx) {
    ctx.drawImage(
            getPicture("../maps/img", "map_new", "jpg")
            , Math.floor(-dx)
            , Math.floor(-dy));
}
function drawMapFromCanvasMap(ctx) {
    ctx.drawImage(
            mapCanvas.canvas
            , Math.floor(-dx * SCALE)
            , Math.floor(-dy * SCALE));
}
function drawMap(ctx) {
    if (dx < (mapW / 2) && dy < (mapH / 2)) {
        ctx.drawImage(
                getPicture("../maps/img", "a_1_1", "jpg")
                , Math.floor(-dx)
                , Math.floor(-dy));
    } else if (dx >= (mapW / 2) && dx < mapW && dy < (mapH / 2)) {
        ctx.drawImage(
                getPicture("../maps/img", "a_1_2", "jpg")
                , Math.floor(-dx + mapW / 2)
                , Math.floor(-dy));
    } else if (dx >= mapW && dy < mapH / 2) {
        ctx.drawImage(
                getPicture("../maps/img", "a_1_3", "jpg")
                , Math.floor(-dx + mapW)
                , Math.floor(-dy));
    }
    else if (dx < (mapW / 2) && dy >= mapH / 2 && dy < (mapH)) {
        ctx.drawImage(
                getPicture("../maps/img", "a_2_1", "jpg")
                , Math.floor(-dx)
                , Math.floor(-dy + mapH / 2));
    } else if (dx >= (mapW / 2) && dx < mapW && dy >= mapH / 2 && dy < (mapH)) {
        ctx.drawImage(
                getPicture("../maps/img", "a_2_2", "jpg")
                , Math.floor(-dx + (mapW / 2))
                , Math.floor(-dy + mapH / 2));
    } else if (dx >= mapW && dy >= mapH / 2 && dy < (mapH)) {
        ctx.drawImage(
                getPicture("../maps/img", "a_2_3", "jpg")
                , Math.floor(-dx + mapW)
                , Math.floor(-dy + mapH / 2));
    }
    else if (dx < (mapW / 2) && dy >= mapH) {
        ctx.drawImage(
                getPicture("../maps/img", "a_3_1", "jpg")
                , Math.floor(-dx)
                , Math.floor(-dy + mapH));
    } else if (dx >= (mapW / 2) && dx < mapW && dy >= mapH) {
        ctx.drawImage(
                getPicture("../maps/img", "a_3_2", "jpg")
                , Math.floor(-dx + (mapW / 2))
                , Math.floor(-dy + mapH));
    } else if (dx >= mapW && dy >= mapH) {
        ctx.drawImage(
                getPicture("../maps/img", "a_3_3", "jpg")
                , Math.floor(-dx + mapW)
                , Math.floor(-dy + mapH));
    }
}
function drawFog(ctx) {
    ctx.globalAlpha = 0.5;
    ctx.beginPath();
    for (var n = 0; n < objects.heroes.length; n++) {
        objects.heroes[n].groupCanSee = n;
    }
// $("#log").html("");
    for (var n = 0; n < objects.heroes.length; n++) {
        for (var h = 0; h < objects.heroes.length; h++) {
            var d = distans(objects.heroes[h].x, objects.heroes[h].y, objects.heroes[n].x, objects.heroes[n].y);
            if (d < (objects.heroes[h].canSee + objects.heroes[n].canSee) && objects.heroes[h].id != objects.heroes[n].id) {
                objects.heroes[h].groupCanSee = objects.heroes[n].groupCanSee;
            }
        }
        ctx.moveTo(objects.heroes[n].x - dx + 350, objects.heroes[n].y - dy);
        ctx.arc(objects.heroes[n].x - dx, objects.heroes[n].y - dy, 350, 0, 2 * Math.PI);
    }
    /*(for (var g = 0; g < objects.heroes.length; g++) {
     var group = [];
     for (var n = 0; n < objects.heroes.length; n++) {
     if (objects.heroes[n].groupCanSee == g) {
     group.push(objects.heroes[n]);
     }
     }
     // createPoligonGroupCanSee(group);
     }*/
    ctx.moveTo(0, 0);
    ctx.lineTo(CANVAS_WIDTH / SCALE, 0);
    ctx.lineTo(CANVAS_WIDTH / SCALE, CANVAS_HEIGHT / SCALE);
    ctx.lineTo(0, CANVAS_HEIGHT / SCALE);
    ctx.lineTo(0, 0);
    ctx.closePath();
    ctx.fill();
    ctx.globalAlpha = 1;
}
function  createPoligonGroupCanSee(group) {
    if (group.length == 0) {
        return;
    }
//for (var n = 0; n < group.length; n++) {
    var n = 0;
    var ugol = 0;
    var stpointx = group[n].x - dx + 350;
    var stpointy = group[n].y - dy;
    var iscollise = false;
    var iter = 0;
    var p = {x: 0 - dx, y: 0 - dy};
    canvas.moveTo(stpointx, stpointy);
    distans(stpointx, stpointy, p.x, p.y)
    while (iter < 100) {
//for (var v = ugol; v < (ugol + Math.PI * 2); v = v + Math.PI / 16) {
        p = rotatePoint(group[n].x - dx + 350, group[n].y - dy, group[n].x - dx, group[n].y - dy, ugol);
        for (var l = 0; l < group.length; l++) {
            if (distans(group[l].x - dx, group[l].y - dy, p.x, p.y) < group[l].canSee && n != l)
            {
                iscollise = true;
                n = l;
                var ll = angleVector(group[l].x - dx, group[l].y - dy, p.x, p.y);
            }
        }
        if (!iscollise) {
            canvas.lineTo(p.x, p.y);
        }
        ugol = ugol + Math.PI / 16;
        iter++;
    }
}
function spliceHeroes() {
    for (var j = 0; j < objects.heroes.length; j++) {
        if (objects.heroes[j].isExist) {
            objects.heroes[j].isExist = false;
        } else {
            objects.heroes.splice(j, 1);
            j--;
        }
    }
}
function spliceArrows() {
    for (var j = 0; j < objects.arrows.length; j++) {
        if (objects.arrows[j].isExist) {
            objects.arrows[j].isExist = false;
        } else {
            var blood = {
                x: objects.arrows[j].x,
                y: objects.arrows[j].y,
                r: Math.floor(Math.random() * 360),
                dir: objects.arrows[j].dir,
                type: 2,
                f: 0
            }
            objects.explosionBloods.push(blood);
            objects.arrows.splice(j, 1);
            j--;
        }
    }
    // $("#log").append(objects.arrows.length);
}
function spliceTowers() {
    for (var j = 0; j < objects.towers.length; j++) {
        if (objects.towers[j].isExist) {
            objects.towers[j].isExist = false;
        } else {
            objects.towers.splice(j, 1);
            j--;
        }
    }
}
function getBObject(id) {
    for (var j = 0; j < objects.heroes.length; j++) {
        if (objects.heroes[j].id == id) {
            return objects.heroes[j];
        }
    }
    for (var j = 0; j < objects.towers.length; j++) {
        if (objects.towers[j].id == id) {
            return objects.towers[j];
        }
    }
    return null;
}
function resetselectedObject() {
    for (var k = 0; k < objects.unitsStaticInfo.length; k++) {
        if (selectedObject.id == objects.unitsStaticInfo[k].gameId) {
            var tmpBasicHero = getBasicHero(objects.unitsStaticInfo[k].heroId);
            $("#controlPanel .hero .name").html(tmpBasicHero.name);
            $("#controlPanel .hero .hp .value").html(selectedObject.hp + " / " + selectedObject.maxHp);
            $("#controlPanel .hero .hp .percent").css("width", ((130 * selectedObject.hp) / selectedObject.maxHp) + "px");
            $("#controlPanel .hero .mp .value").html(selectedObject.mp + " / " + selectedObject.maxMp);
            $("#controlPanel .hero .mp .percent").css("width", ((130 * selectedObject.mp) / selectedObject.maxMp) + "px");
            $("#controlPanel .hero .img").css("background-image", "url(img/heroes_pic/" + tmpBasicHero.dir + "_full.png)");
            $("#controlPanel .hero .parametrs1").html(""
                    + "Атака: " + selectedObject.damage + "</br>"
                    + "Защита: " + selectedObject.armor + "</br>"
                    + "Уровень: " + selectedObject.lvl + "</br>"
                    + "Опыт: " + selectedObject.exp + "</br>");
            $("#controlPanel .hero .parametrs2").html(""
                    + "Сила: " + selectedObject.strength + "</br>"
                    + "Ловкость: " + selectedObject.agility + "</br>"
                    + "Разум: " + selectedObject.intelligence + "</br>");
        }
    }
}
function resetSelectedTower() {
    var tmpObj = getBObject(selectedObject.id);
    if (tmpObj != null) {
        $("#controlPanel .hero .name").html("Вышка");
        $("#controlPanel .hero .hp .value").html(selectedObject.hp + " / " + selectedObject.maxHp);
        $("#controlPanel .hero .hp .percent").css("width", ((130 * selectedObject.hp) / selectedObject.maxHp) + "px");
        $("#controlPanel .hero .mp .value").html(selectedObject.mp + " / " + selectedObject.maxMp);
        $("#controlPanel .hero .mp .percent").css("width", ((130 * selectedObject.mp) / selectedObject.maxMp) + "px");
        $("#controlPanel .hero .img").css("background-image", "url(img/heroes/" + tmpObj.dir + "/1.png)");
        $("#controlPanel .hero .parametrs1").html(""
                + "Атака: " + selectedObject.damage + "</br>"
                + "Защита: " + selectedObject.armor + "</br>");
    }
}
function moveLeft() {
    var x = dx - speedMoveCanvas;
    setDxDy(x, dy);
}
function moveRight() {
    var x = dx + speedMoveCanvas;
    setDxDy(x, dy);
}
function moveUp() {
    var y = dy - speedMoveCanvas;
    setDxDy(dx, y);
}
function moveDown() {
    var y = dy + speedMoveCanvas;
    setDxDy(dx, y);
}
function setDxDy(x, y) {
    dx = x;
    dy = y;
    if (x < 0) {
        dx = 0;
    } else if (x > 2 * mapW - CANVAS_WIDTH / SCALE) {
        dx = Math.floor(2 * mapW - CANVAS_WIDTH / SCALE);
    }
    if (y < 0) {
        dy = 0;
    } else if (y > 2 * mapH - CANVAS_HEIGHT / SCALE) {
        dy = Math.floor(2 * mapH - CANVAS_HEIGHT / SCALE);
    }
}
function getCanvasAnimateByNameAnimate(obj, type_animation) {
    if (type_animation == "stand") {
        return obj.canvas_stand;
    } else if (type_animation == "run") {
        return obj.canvas_run;
    } else if (type_animation == "atack1") {
        return obj.canvas_atack1;
    } else if (type_animation == "atack2") {
        return obj.canvas_atack2;
    } else if (type_animation == "atack3") {
        return obj.canvas_atack3;
    }
}
function drawBigSprite(canvas, img, w) {
    var k = 0;
    for (k = 0; k < img.width; k = k + 4000) {
        if (k + 4000 < img.width) {
            canvas.drawImage(img,
                    k, 0, 4000, w,
                    k, 0, 4000, w);
        } else {
            canvas.drawImage(img,
                    k, 0, img.width - k, w,
                    k, 0, img.width - k, w);
        }
    }
}
function initCanvasHeroes(heroList, n, fnSucces) {
    if (n < heroList.length) {
        var widthC = 0;
        //if (heroList[n].typeId == 1 || heroList[n].typeId == 2 || heroList[n].typeId == 3) {

        //}
        $("#" + heroList[n].id + "_stand").remove();
        $("#" + heroList[n].id + "_run").remove();
        $("#" + heroList[n].id + "_atack1").remove();
        $("#" + heroList[n].id + "_atack2").remove();
        $("#" + heroList[n].id + "_atack3").remove();
        $("#play").append("<canvas class='heroCanvas' id='" + heroList[n].id + "_stand' style='display: none;'></canvas>");
        $("#play").append("<canvas class='heroCanvas' id='" + heroList[n].id + "_run' style='display: none;'></canvas>");
        $("#play").append("<canvas class='heroCanvas' id='" + heroList[n].id + "_atack1' style='display: none;'></canvas>");
        $("#play").append("<canvas class='heroCanvas' id='" + heroList[n].id + "_atack2' style='display: none;'></canvas>");
        $("#play").append("<canvas class='heroCanvas' id='" + heroList[n].id + "_atack3' style='display: none;'></canvas>");
        var obj = {
            hero: heroList[n],
            canvas_stand: document.getElementById(heroList[n].id + "_stand").getContext("2d"),
            canvas_run: document.getElementById(heroList[n].id + "_run").getContext("2d"),
            canvas_atack1: document.getElementById(heroList[n].id + "_atack1").getContext("2d"),
            canvas_atack2: document.getElementById(heroList[n].id + "_atack2").getContext("2d"),
            canvas_atack3: document.getElementById(heroList[n].id + "_atack3").getContext("2d"),
        }
        animationCanvasList.push(obj);
        var imgRun = new Image();
        var imgStand = new Image();
        var imgAtack1 = new Image();
        var imgAtack2 = new Image();
        var imgAtack3 = new Image();
        var imgShadow = new Image();
        var w = heroSize;
        if (heroList[n].typeId == 4) {
            w = 120;
        }
        imgShadow.src = "img/resource/shadow.png";
        imgShadow.onload = function () {
            imgStand.src = "img/heroes/" + heroList[n].dir + "/stand.png";
            imgStand.onload = function () {
                $("#" + obj.hero.id + "_stand").attr("height", Math.round(imgStand.height * SCALE) + 1);
                $("#" + obj.hero.id + "_stand").attr("width", Math.round(imgStand.width * SCALE) + 1);
                obj.canvas_stand.scale(SCALE, SCALE);
                for (var i = 0; i < imgStand.width; i = i + w) {
                    obj.canvas_stand.drawImage(imgShadow, i + Math.round(w / 2) - 55, Math.round(w / 2) - 55);
                }
                //obj.canvas_stand.drawImage(imgStand, 0, 0);
                drawBigSprite(obj.canvas_stand, imgStand, w);
                imgRun.src = "img/heroes/" + heroList[n].dir + "/run.png";
                imgRun.onload = function () {
                    $("#" + obj.hero.id + "_run").attr("height", Math.round(imgRun.height * SCALE) + 1);
                    $("#" + obj.hero.id + "_run").attr("width", Math.round(imgRun.width * SCALE) + 1);
                    obj.canvas_run.scale(SCALE, SCALE);
                    for (var i = 0; i < imgRun.width; i = i + w) {
                        obj.canvas_run.drawImage(imgShadow, i + Math.round(w / 2) - 55, Math.round(w / 2) - 55);
                    }
                    //obj.canvas_run.drawImage(imgRun, 0, 0);
                    drawBigSprite(obj.canvas_run, imgRun, w);
                    imgAtack1.src = "img/heroes/" + heroList[n].dir + "/atack1.png";
                    imgAtack1.onload = function () {
                        $("#" + obj.hero.id + "_atack1").attr("height", Math.round(imgAtack1.height * SCALE) + 1);
                        $("#" + obj.hero.id + "_atack1").attr("width", Math.round(imgAtack1.width * SCALE) + 1);
                        obj.canvas_atack1.scale(SCALE, SCALE);
                        for (var i = 0; i < imgAtack1.width; i = i + w) {
                            obj.canvas_atack1.drawImage(imgShadow, i + Math.round(w / 2) - 55, Math.round(w / 2) - 55);
                        }
                        //obj.canvas_atack1.drawImage(imgAtack1, 0, 0);
                        drawBigSprite(obj.canvas_atack1, imgAtack1, w);
                        imgAtack2.src = "img/heroes/" + heroList[n].dir + "/atack2.png";
                        imgAtack2.onload = function () {
                            $("#" + obj.hero.id + "_atack2").attr("height", Math.round(imgAtack2.height * SCALE) + 1);
                            $("#" + obj.hero.id + "_atack2").attr("width", Math.round(imgAtack2.width * SCALE) + 1);
                            obj.canvas_atack2.scale(SCALE, SCALE);
                            for (var i = 0; i < imgAtack2.width; i = i + w) {
                                obj.canvas_atack2.drawImage(imgShadow, i + Math.round(w / 2) - 55, Math.round(w / 2) - 55);
                            }
                            //obj.canvas_atack2.drawImage(imgAtack2, 0, 0);
                            drawBigSprite(obj.canvas_atack2, imgAtack2, w);
                            imgAtack3.src = "img/heroes/" + heroList[n].dir + "/atack3.png";
                            imgAtack3.onload = function () {
                                $("#" + obj.hero.id + "_atack3").attr("height", Math.round(imgAtack3.height * SCALE) + 1);
                                $("#" + obj.hero.id + "_atack3").attr("width", Math.round(imgAtack3.width * SCALE) + 1);
                                obj.canvas_atack3.scale(SCALE, SCALE);
                                for (var i = 0; i < imgAtack3.width; i = i + w) {
                                    obj.canvas_atack3.drawImage(imgShadow, i + Math.round(w / 2) - 55, Math.round(w / 2) - 55);
                                }
                                //obj.canvas_atack3.drawImage(imgAtack3, 0, 0);
                                drawBigSprite(obj.canvas_atack3, imgAtack3, w);
                                n = n + 1;
                                var pr = Math.round(n / heroList.length * 100);
                                $("#initWindow").html("Масштабирование графики " + SCALE + "</br>" + pr + "%");
                                initCanvasHeroes(heroList, n, fnSucces);
                            }
                        }
                    }
                }
            }
        }
    } else {
        fnSucces();
    }
}
function getAnimationCanvas(heroId, type_animation) {
    for (var n = 0; n < animationCanvasList.length; n++) {
        if (animationCanvasList[n].hero.id == heroId) {
            //alert(getCanvasAnimateByNameAnimate(animationCanvasList[n], type_animation));
            return getCanvasAnimateByNameAnimate(animationCanvasList[n], type_animation);
        }
    }
}